package com.apexsoft.front.common.db.mysql;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;

import com.apexsoft.front.common.utils.LogUtil;

/**
 * @Description: 解析器采用getObject解析 支持JAVA数据类型如下 String<br/>
 *               Boolean<br/>
 *               Integer<br/>
 *               BigDecimal<br/>
 *               Long<br/>
 *               Float<br/>
 *               Double<br/>
 *               Timestamp<br/>
 *               String<br/>
 *               byte[]<br/>
 * 
 * @Author zhengjin
 * @Date 2014-8-16 上午11:24:03
 * @Version 1.0
 */
public class MysqlResultSetParser {
	private static Map<String, Class<?>> mapper = new HashMap<String, Class<?>>();
	static {
		mapper.put("BIT", Boolean.class);

		mapper.put("INT UNSIGNED", Integer.class);
		mapper.put("INT", Integer.class);

		mapper.put("DECIMAL UNSIGNED", BigDecimal.class);
		mapper.put("DECIMAL", BigDecimal.class);

		mapper.put("BIGINT UNSIGNED", Long.class);
		mapper.put("BIGINT", Long.class);

		mapper.put("FLOAT UNSIGNED", Float.class);
		mapper.put("FLOAT", Float.class);

		mapper.put("DOUBLE UNSIGNED", Double.class);
		mapper.put("DOUBLE", Double.class);

		mapper.put("DATE", Date.class);
		mapper.put("DATETIME", String.class);
		mapper.put("TIMESTAMP", Timestamp.class);

		mapper.put("VARCHAR", String.class);

		mapper.put("BLOB", byte[].class);

		// mapper.put("UNKNOWN", Object.class);
		// mapper.put("TINYINT UNSIGNED", Object.class);
		// mapper.put("TINYINT", Object.class);
		// mapper.put("SMALLINT UNSIGNED", Object.class);
		// mapper.put("SMALLINT", Object.class);
		// mapper.put("MEDIUMINT UNSIGNED", Object.class);
		// mapper.put("MEDIUMINT", Object.class);
		// mapper.put("VARBINARY", Object.class);
		// mapper.put("BINARY", Object.class);
		// mapper.put("ENUM", Object.class);
		// mapper.put("YEAR", Object.class);
		// mapper.put("SET", Object.class);
		// mapper.put("GEOMETRY", Object.class);
		// mapper.put("TINYBLOB", byte[].class);
		// mapper.put("MEDIUMBLOB", byte[].class);
		// mapper.put("LONGBLOB", byte[].class);
		// mapper.put("DATE", Date.class);
		// mapper.put("TIME", Time.class);
	}

	public static void parse(ResultSet rs, int row, ReflectObject o) throws SQLException {
		ResultSetMetaData rsmd = rs.getMetaData();
		for (int i = 1; i <= rsmd.getColumnCount(); i++) {
			Class<?> type = mapper.get(rsmd.getColumnTypeName(i));
			Object value = null;
			if (type == Boolean.class) {
				value = Boolean.valueOf(rs.getBoolean(i));
			} else if (type == BigDecimal.class) {
				value = rs.getBigDecimal(i);
			} else if (type == Integer.class) {
				value = Integer.valueOf(rs.getInt(i));
				if (((Integer) value).intValue() == 0) {
					if (rs.getString(i) == null) {
						value = null;
					}
				}
			} else if (type == Long.class) {
				value = Long.valueOf(rs.getLong(i));
				if (((Long) value).longValue() == 0L) {
					if (rs.getString(i) == null) {
						value = null;
					}
				}
			} else if (type == Float.class) {
				value = Float.valueOf(rs.getFloat(i));
				if (((Float) value).floatValue() == 0f) {
					if (rs.getString(i) == null) {
						value = null;
					}
				}
			} else if (type == Double.class) {
				value = Double.valueOf(rs.getDouble(i));
				if (((Double) value).doubleValue() == 0d) {
					if (rs.getString(i) == null) {
						value = null;
					}
				}
			} else if (type == Timestamp.class) {
				value = rs.getTimestamp(i);
			} else if (type == Date.class) {
				value = rs.getDate(i);
			} else if (type == String.class) {
				value = rs.getString(i);
			}
			String filedName = DaoSupportMapper.parseFieldName(rsmd.getColumnName(i));
			o.setProperty(filedName, value);
			try {
				Field field = o.getClass().getDeclaredField(filedName);
				field.setAccessible(true);
				field.set(o, value);
			} catch (NoSuchFieldException e) {
				// LogUtil.debugLog(MysqlResultSetParser.class, "no this field:"
				// + filedName);
			} catch (IllegalArgumentException e) {
				LogUtil.errorLog(MysqlResultSetParser.class, "IllegalArgument in this field:" + filedName, e);
			} catch (IllegalAccessException e) {
				LogUtil.errorLog(MysqlResultSetParser.class, "IllegalAccess in this field:" + filedName, e);
			}
		}
	}
}
